/*
 *  ImageFilePng.cpp
 *  Ray Tracing
 *
 *  Created by Jean-Marc Comby + Romain Dequesne on Wed May 19 2004.
 *  Copyright (c) 2004. All rights reserved.
 *
 */

#include "ImageFilePng.hpp"

#include "pngwriter.hpp"

#include "Utils/Erreur.hpp"

#include <stdlib.h>

using namespace std;

/**
 * Construceur permettant d'initialiser une ImageFilePng à partir
 * d'une Image, un nom de fichier et la qualité voulue.
 *
 * @param im pointeur sur l'Image que l'on veut sauver.
 * @param nom nom du fichier dans lequel l'Image sera sauvée.
 */
ImageFilePng::ImageFilePng(Image *im, const string& nom)
  : ImageFile( im, nom )
{}

/**
 * Constructeur permettant d'initialiser une ImageFilePng de zéro.
 *
 * @param h dimension horizontale de l'image.
 * @param l dimension verticale de l'image.
 * @param nom nom du fichier dans lequel l'Image sera sauvée.
 */
ImageFilePng::ImageFilePng(const unsigned int& h, const unsigned int& l,
			   const string& nom)
  : ImageFile( h, l, nom )
{}

/**
 * Le destructeur n'a rien de spécial à faire.
 */
ImageFilePng::~ImageFilePng()
{}

/**
 * La méthode ouvre le fichier. Si l'ouverture n'est pas possible, une
 * erreur est écrite dans le log, puis on quitte la méthode.
 *
 * Ensuite les différentes structures nécessaires sont initialisées et
 * remplies, puis le fichier est écrit et fermé.
 */
void ImageFilePng::affiche()
{
  cout << "Sauvegarde de l'image " << outputfile << endl;

  pngwriter pngImage( Largeur, Hauteur, 0, outputfile,
		      sizeof( ComposantCouleur ) );

  unsigned int pixel_x, pixel_y;

  Couleur color;

  int r, v, b;

  for ( pixel_y = 0; pixel_y < Hauteur; pixel_y++ )
    {
      for ( pixel_x = 0; pixel_x < Largeur; pixel_x++ )
	{
	  color = Screen[ pixel_x ][ Hauteur - pixel_y - 1 ];
	  r = color.rouge();
	  v = color.vert();
	  b = color.bleu();
	  r <<= 8;
	  v <<= 8;
	  b <<= 8;
	  pngImage.plot( pixel_x, pixel_y,
			 //color.rouge(), color.vert(), color.bleu() );
			 r, v, b );
	}
    }

  pngImage.close();

//   FILE *fp;
//   png_structp png_ptr;
//   png_infop info_ptr;
//   png_text text_ptr[3]; // permet d ecrire une description
	
//   /* open the file */
//   fp = fopen(outputfile, "wb");
//   if (fp == NULL)
//     {
//       Erreur err(true,1,"Erreur d'ouverture du fichier","Classe ImageFilePng");
//       err.ecrire("Erreur.txt");
//       cerr << "Crash du programme. Consulter le log pour plus d'info." << endl;
//       exit(1);
//     }
//   /* Create and initialize the png_struct with the desired error handler
//    * functions.  If you want to use the default stderr and longjump method,
//    * you can supply NULL for the last three parameters.  We also check that
//    * the library version is compatible with the one used at compile time,
//    * in case we are using dynamically linked libraries.  REQUIRED.
//    */
//   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
// 				    NULL, NULL, NULL);
	
//   if (png_ptr == NULL)
//     {
//       fclose(fp);
//       Erreur err(true,1,"Erreur d'écriture dans struct png","Classe ImageFilePng");
//       err.ecrire("Erreur.txt");
//       cerr << "Crash du programme. Consulter le log pour plus d'info." << endl;
//       exit(1);
//     }
	
//   /* Allocate/initialize the image information data.  REQUIRED */
//   info_ptr = png_create_info_struct(png_ptr);
//   if (info_ptr == NULL)
//     {
//       fclose(fp);
//       png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
//       Erreur err(true,1,"Erreur d'allocation image data png","Classe ImageFilePng");
//       err.ecrire("Erreur.txt");
//       cerr << "Crash du programme. Consulter le log pour plus d'info." << endl;
//       exit(1);
//     }
	
//   /* Set error handling.  REQUIRED if you aren't supplying your own
//    * error handling functions in the png_create_write_struct() call.
//    */
//   if (setjmp(png_jmpbuf(png_ptr)))
//     {
//       /* If we get here, we had a problem reading the file */
//       fclose(fp);
//       png_destroy_write_struct(&png_ptr, &info_ptr);
//       Erreur err(true,1,"problem reading the file","Classe ImageFilePng");
//       err.ecrire("Erreur.txt");
//       cerr << "Crash du programme. Consulter le log pour plus d'info." << endl;
//       exit(1);
//     }
	
//   /* One of the following I/O initialization functions is REQUIRED */
//   /* set up the output control if you are using standard C streams */
//   png_init_io(png_ptr, fp);
	
//   /* Set the image information here.  Width and height are up to
//    * 2^31, bit_depth is one of 1, 2, 4, 8, or 16, but valid
//    * values also depend on the color_type selected. color_type
//    * is one of PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA,
//    * PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, or
//    * PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either
//    * PNG_INTERLACE_NONE or PNG_INTERLACE_ADAM7, and the
//    * compression_type and filter_type MUST currently be
//    * PNG_COMPRESSION_TYPE_BASE and
//    * PNG_FILTER_TYPE_BASE. REQUIRED
//    */
//   png_set_IHDR(png_ptr, info_ptr, Largeur, Hauteur, sizeof(ComposantCouleur)*8,
// 	       PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
// 	       PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
	
//   /* Optionally write comments into the image */
//   text_ptr[0].key = "Title";
//   text_ptr[0].text = (char*)outputfile;
//   text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
//   text_ptr[1].key = "Author";
//   text_ptr[1].text = "Romain Dequesne + Jean-Marc Comby";
//   text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
//   text_ptr[2].key = "Description";
//   text_ptr[2].text = "Image generer par raytracer";
//   text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
// #ifdef PNG_iTXt_SUPPORTED
//   text_ptr[0].lang = NULL;
//   text_ptr[1].lang = NULL;
//   text_ptr[2].lang = NULL;
// #endif
//   png_set_text(png_ptr, info_ptr, text_ptr, 3);
	
//   /* Write the file header information.  REQUIRED */
//   png_write_info(png_ptr, info_ptr);
	
//   // Allocation d un tableau tampon
//   ComposantCouleur **row_pointers;
//   row_pointers=(ComposantCouleur **)malloc(sizeof(ComposantCouleur *)*Hauteur);
//   for (unsigned int i(0); i<Hauteur; i++)
//     {
//       row_pointers[i]=(ComposantCouleur *)malloc(sizeof(ComposantCouleur)*Largeur*3);
//     }
//   // copie de notre image dans ce tableau tampon
//   Couleur color;
//   for (unsigned int pixel_y(0); pixel_y < Hauteur; pixel_y++)
//     {
//       unsigned int width(0);
//       for (unsigned int pixel_x(0); pixel_x < Largeur; pixel_x++)
// 	{
// 	  color=Screen[pixel_x][pixel_y];
// 	  row_pointers[pixel_y][width]=color.rouge();
// 	  width++;
// 	  row_pointers[pixel_y][width]=color.vert();
// 	  width++;
// 	  row_pointers[pixel_y][width]=color.bleu();
// 	  width++;
// 	}
//     }
//   png_write_image(png_ptr, row_pointers);
	
//   /* It is REQUIRED to call this to finish writing the rest of the file */
//   png_write_end(png_ptr, info_ptr);
	
//   // Destruction du tableau tampon
//   for (unsigned int i(0); i<Hauteur; i++)
//     free(row_pointers[i]);
//   free(row_pointers);
	
//   /* clean up after the write, and free any memory allocated */
//   png_destroy_write_struct(&png_ptr, &info_ptr);
	
//   /* close the file */
//   fclose(fp);
}
